Skip to content

[Php81] Skip ArrayToFirstClassCallableRector when the arg type does not accept a Closure - #8288

Merged
TomasVotruba merged 1 commit into
mainfrom
fix-array-to-first-class-callable-array-param
Aug 4, 2026
Merged

[Php81] Skip ArrayToFirstClassCallableRector when the arg type does not accept a Closure#8288
TomasVotruba merged 1 commit into
mainfrom
fix-array-to-first-class-callable-array-param

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Fixes rectorphp/rector#9563

A first class callable is a Closure. When the array callable is passed as an argument to a parameter that cannot hold a Closurearray, or a union like string|array|SomeObject|null — the converted code fatals at runtime:

Uncaught TypeError: DemoFile::__construct(): Argument #1 ($argument) must be of type SomeObjectAsArgument|array|string|null, Closure given

Before / after

final class SomeObjectWithArrayArgument
{
    public function __construct(
        public string|array|SomeExternalObject|null $argument
    ) {
    }
}
 public function run()
 {
-    return new SomeObjectWithArrayArgument([$this, 'name']);
+    return new SomeObjectWithArrayArgument([$this, 'name']); // unchanged now
 }

A callable parameter still converts:

 public function run(SomeObjectWithArrayArgument $someObjectWithArrayArgument)
 {
-    $someObjectWithArrayArgument->withCallable([$this, 'name']);
+    $someObjectWithArrayArgument->withCallable($this->name(...));
 }

How

New ArgNotAcceptingClosureNodeVisitor (a DecoratingNodeVisitorInterface, so attribute decoration stays separate from node changes) resolves the called function/method reflection, matches each array argument to its parameter — by name for named args, by position otherwise, falling back to a trailing variadic — and marks the argument with AttributeKey::IS_ARG_NOT_ACCEPTING_CLOSURE when the parameter type rejects Closure. The rule bails out on that attribute.

…sure

A first class callable is a Closure. Passing it to a parameter typed
"array" or "string|array|null" is a fatal TypeError at runtime.

Fixes rectorphp/rector#9563
@TomasVotruba
TomasVotruba merged commit 60130ec into main Aug 4, 2026
64 checks passed
@TomasVotruba
TomasVotruba deleted the fix-array-to-first-class-callable-array-param branch August 4, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect behavior of ArrayToFirstClassCallableRector

1 participant